%option noyywrap
%option yylineno

%{
#include <stdio.h>

enum Token {
    INT=258,  BREAK, CONTINUE, FLOAT, VOID, CONST, RETURN, IF, ELSE, FOR, WHILE, DO,
    ID, INT_LIT, FLOAT_LIT,
    LE, GT, GE,EQ, NE, LT,
    MINUS, DIV, MOD, AND, OR, NOT, ADD, MUL, TILDE, ASSIGN,
    LP, RP, LB, QUESTION, COLON, RB, LC, RC, COMMA, SEMICOLON,
    
    LEX_ERR
};

%}


commentlinebegin "//"
commentlineelement .
commentlineend \n
%x COMMENTLINE

commentbegin "/*"
commentelement .|\n
commentend "*/"
%x COMMENT

id   	[_a-zA-Z][_a-zA-Z0-9]* 
hex     0[Xx][a-fA-F0-9]+
formatchar [\r\n\t ]+
intError 08[0-9]+ 
float  	[0-9]*\.[0-9]+|[0-9]+\.
int    	0[1-7][0-9]+|[0-9]|[1-9][0-9]+
expo    [Ee][+-]?[0-9]+[f]?

%%
"int" {printf("%s : INT\n", yytext); return INT; }
"float" {printf("%s : FLOAT\n", yytext); return FLOAT; }
"void" {printf("%s : VOID\n", yytext); return VOID; }
"const" {printf("%s : CONST\n", yytext); return CONST; }
"return" {printf("%s : RETURN\n", yytext); ; return RETURN; }
"if" {printf("%s : IF\n", yytext); return IF; }
"else" {printf("%s : ELSE\n", yytext); return ELSE; }
"for" {printf("%s : FOR\n", yytext); return FOR; }
"while" {printf("%s : WHILE\n", yytext); return WHILE; }
"do" {printf("%s : DO\n", yytext); return DO; }
"break" {printf("%s : BREAK\n", yytext); return BREAK; }
"continue" {printf("%s : CONTINUE\n", yytext); return CONTINUE; }

"," {printf("%s : COMMA\n", yytext); return COMMA; }
":" {printf("%s : COLON\n", yytext); return COLON; }
";" {printf("%s : SEMICOLON\n", yytext); return SEMICOLON; }
"?" {printf("%s : QUESTION\n", yytext); return QUESTION; }
"!" {printf("%s : NOT\n", yytext); return NOT; }

"(" {printf("%s : LP\n", yytext); return LP; }
")" {printf("%s : RP\n", yytext); return RP; }
"[" {printf("%s : LB\n", yytext); return LB; }
"]" {printf("%s : RB\n", yytext); return RB; }
"{" {printf("%s : LC\n", yytext); return LC; }
"}" {printf("%s : RC\n", yytext); return RC; }

"%" {printf("%s : MOD\n", yytext); return MOD; }
"=" {printf("%s : ASSIGN\n", yytext); return ASSIGN; }
"+" {printf("%s : ADD\n", yytext); return ADD; }
"-" {printf("%s : MINUS\n", yytext); return MINUS; }
"*" {printf("%s : MUL\n", yytext); return MUL; }
"/" {printf("%s : DIV\n", yytext); return DIV; }

"<" {printf("%s : LT\n", yytext); return LT; }
">" {printf("%s : GT\n", yytext); return GT; }
"<=" {printf("%s : LE\n", yytext); return LE; }
">=" {printf("%s : GE\n", yytext); return GE; }
"!=" {printf("%s : NE\n", yytext); return NE; }
"==" {printf("%s : EQ\n", yytext); return EQ; }
"&&," {printf("%s : AND\n", yytext); return AND; }
"||" {printf("%s : OR\n", yytext); return OR; }

{formatchar} {;}

{id} {printf("%s : ID\n", yytext); return ID;}
{commentbegin} {BEGIN COMMENT;}
<COMMENT>{commentelement} {}
<COMMENT>{commentend} {BEGIN INITIAL;}
{commentlinebegin} {BEGIN COMMENTLINE;}
<COMMENTLINE>{commentlineelement} {}
<COMMENTLINE>{commentlineend} {BEGIN INITIAL;}
({int}|{float}){expo} {printf("%s : FLOAT_LIT\n", yytext); return FLOAT_LIT;}
{intError} { 
printf("Lexical error - line %d : %s\n", yylineno, yytext);
}
{int} { printf("%s : INT_LIT\n", yytext); return INT_LIT; }
{hex} { printf("%s : INT_LIT\n", yytext); return INT_LIT; }
({int}|{hex}|{float}|(({int}|{float}){expo}))[\.a-zA-Z_][\.a-zA-Z_0-9]* { 
printf("Lexical error - line %d : %s\n", yylineno, yytext);
}
{float} {printf("%s : FLOAT_LIT\n", yytext); return FLOAT_LIT;}




%%


int main(int argc, char** argv) {
    if(argc > 1) {
        if(!(yyin = fopen(argv[1], "r"))) {
           perror(argv[1]); 
           return  1; 
        }       



        while(yylex());


        fclose(yyin);
    } else printf("No source file given!\n"); 

    return 0; 
}

